<template>
  <div class="img-gird-upload">
    <div class="img-gird-upload-btns" v-if="showBtn">
      <a-radio-group>
        <a-button type="link" @click="onAdd">
          <template #icon>
            <component :is="$Icon['PlusOutlined']"></component>
          </template>
          添加
        </a-button>
        <a-button type="link" @click="onReset">
          <template #icon>
            <component :is="$Icon['RedoOutlined']"></component>
          </template>
          重置
        </a-button>
      </a-radio-group>
      <div class="img-gird-upload-tip ant-typography ant-typography-secondary">
        最多可以添加{{ fileLimit }}张图片
      </div>
    </div>
    <div class="img-gird-upload-content">
      <draggable
        v-model="imgs"
        tag="ul"
        :sort="true"
        animation="300"
        handle=".img-gird-upload-list-header"
        :class="['img-gird-upload-list']"
        @end="onSortEnd"
      >
        <template #item="{ element, index }">
          <li @mouseenter="onSenter(index)" @mouseleave="onleavue(index)">
            <transition name="fade-in-down">
              <div
                class="img-gird-upload-list-header"
                v-if="sort && fileLimit > 1"
                v-show="element.tool"
              >
                <i class="icon icon-tuodong"></i>
                拖动排序
              </div>
            </transition>
            <div class="img-gird-upload-list-content">
              <img :src="element.src" :style="style" />
            </div>
            <transition name="fade-in-up">
              <div
                class="img-gird-upload-list-footer"
                v-if="sort"
                v-show="element.tool"
              >
                <div @click="onEdit(index)">
                  <a-button type="link" block title="修改">
                    <template #icon>
                      <component :is="$Icon['FormOutlined']"></component>
                    </template>
                  </a-button>
                </div>
                <div @click="onDelete(index)" v-if="fileLimit > 1">
                  <a-button type="link" block title="删除">
                    <template #icon>
                      <component :is="$Icon['DeleteOutlined']"></component>
                    </template>
                  </a-button>
                </div>
              </div>
            </transition>
          </li>
        </template>
      </draggable>
      <div
        class="ant-typography ant-typography-secondary"
        v-if="helpText != ''"
      >
        {{ helpText }}
      </div>
    </div>
    <span v-show="false">{{ src }}</span>
  </div>
</template>

<script lang="ts" setup>
import { ref, getCurrentInstance, toRaw } from "vue";
import { Modal } from "ant-design-vue";
import draggable from "vuedraggable";

/**
 * 参数
 */
interface IProps {
  /**
   * 图片地址 以,分割的  img,img1.img2
   */
  src: string;

  /**
   * 图片宽度
   */
  width?: number;

  /**
   * 图片高度
   */
  height?: number;
  /**
   * 是否排序
   */
  sort?: boolean;

  /**
   * 最大上传文件数量
   */
  fileLimit?: number;

  /**
   * 最大文件大小
   */
  fileSize?: number;
  /**
   * 帮助描述信息
   */
  helpText?: string;

  /**
   * 显示图片圆角大小 比如 10px
   */
  borderRadius?: number;

  /**
   * 是否显示按钮
   */
  showBtn?: boolean;
}

/**
 * 显示的图片数据
 */
interface IImg {
  /**
   * 访问地址
   */
  src: string;

  /**
   * 是否显示操作工具
   */
  tool: boolean;
}

const props = withDefaults(defineProps<IProps>(), {
  width: 200,
  height: 200,
  sort: true,
  fileLimit: 1,
  fileSize: 300 * 1024,
  helpText: "",
  borderRadius: 0,
  showBtn: true,
});

const emits = defineEmits(["update:src"]);

const imgs = ref<IImg[]>([]);

const proxy: any = getCurrentInstance()?.proxy;

const style: any = {
  width: `${props.width}px`,
  height: `${props.height}px`,
  "border-radius": `${props.borderRadius}px`,
};

//初始化数据
const initData = (imgSrc: string) => {
  if (imgSrc == "" || imgSrc == null) {
    return;
  }

  imgSrc.split(",").forEach((img) => {
    imgs.value.push({
      src: img,
      tool: false,
    });
  });
};

initData(props.src);

//添加图片
const onAdd = () => {
  var leng = imgs.value.length;
  if (leng >= props.fileLimit) {
    Modal.error({ content: `添加图片不能超过${props.fileLimit}张` });
    return;
  }
  //计算剩下数量
  var mult = props.fileLimit - leng;

  proxy.$FileUpload(
    {
      fileSize: props.fileSize,
      fileNum: mult,
    },
    (url: string[]) => {
      url.forEach((_url) => {
        let item = {
          src: _url,
          tool: false,
        };
        imgs.value.push(item);
        onEmitUpdate();
      });
    }
  );
};

//重置图片
const onReset = () => {
  imgs.value = [];
  onEmitUpdate();
};

//重新上传指定图片
const onEdit = (index: number) => {
  proxy.$FileUpload(
    {
      fileSize: props.fileSize,
    },
    (url: string[]) => {
      let item = {
        src: url[0],
        tool: false,
      };
      imgs.value.splice(index, 1, item);
      onEmitUpdate();
    }
  );
};

//删除
const onDelete = (index: number) => {
  imgs.value.splice(index, 1);
  onEmitUpdate();
};

//鼠标进入
const onSenter = (i: number) => {
  imgs.value[i].tool = true;
};

//鼠标离开
const onleavue = (i: number) => {
  imgs.value[i].tool = false;
};

//排序结束
const onSortEnd = () => {
  onEmitUpdate();
};

//触发emit事件
const onEmitUpdate = () => {
  let newValue = toRaw(imgs.value);
  let _src = newValue.map((m) => m.src).join(",");
  emits("update:src", _src);
};
</script>

<style scoped>
.img-gird-upload {
  background-color: #fff;
}

.img-gird-upload-btns {
  margin-bottom: 10px;
}

.app-content {
  top: 56px;
}

.img-gird-upload-default-image > div {
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
  background-image: url(https://cmp520.oss-cn-shenzhen.aliyuncs.com/default/empty.jpg);
  background-size: 100% 100%;
}

.img-gird-upload-list {
  padding: 0;
  margin: 0;
}

.img-gird-upload-list > li {
  position: relative;
  display: inline-block;
  margin: 0px 10px 10px 0px;
}

.img-gird-upload-list-header {
  position: absolute;
  left: 0;
  top: 0px;
  width: 100%;
  display: flex;
  display: block;
  color: #fff;
  text-align: center;
  cursor: move;
  background-color: rgba(0, 0, 0, 0.2);
}

.img-gird-upload-list-header:hover {
  background-color: rgba(0, 0, 0, 0.5);
  transition: all 0.5s;
}

.img-gird-upload-list-content > img {
  display: block;
  width: 120px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
}

.img-gird-upload-list-footer {
  position: absolute;
  bottom: 0px;
  left: 0;
  width: 100%;
  display: flex;
  background-color: rgba(0, 0, 0, 0.2);
}

.img-gird-upload-list-footer button {
  color: #fff;
}

.img-gird-upload-list-footer > div {
  flex: 1;
  /* padding: 3px 1px 0px 0px; */
}

.img-gird-upload-tip {
  padding-left: 15px;
  padding-top: 3px;
}

.img-gird-upload-list-footer > div:hover {
  background-color: rgba(0, 0, 0, 0.5);
  transition: all 0.5s;
}

.fade-in-up-enter-active {
  animation: fadeInUp 0.1s 0.1s ease both;
}

@keyframes fadeInUp {
  0% {
    opacity: 0;
    transform: translateY(3px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

.fade-in-down-enter-active {
  animation: fadeInDown 0.1s 0.1s ease both;
}

@keyframes fadeInDown {
  0% {
    opacity: 0;
    transform: translateY(-3px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}
</style>
